package com.maben.udp.service;

import cn.hutool.core.util.HexUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.net.InetSocketAddress;
import java.util.concurrent.Executor;

/**
 * UDP业务处理类，使用多线程处理
 */
@Service
@EnableAsync // 启用异步功能
public class UdpMessageService {

    // 注册为Spring Bean
    @Bean(name = "messageExecutor")
    public Executor messageExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(Runtime.getRuntime().availableProcessors() * 2);
        executor.setMaxPoolSize(50);
        executor.setQueueCapacity(1000);
        executor.setThreadNamePrefix("udp-message-");
        //设置线程池的拒绝策略（Rejected Execution Handler），当线程池无法处理新任务时会执行这段逻辑
        executor.setRejectedExecutionHandler((r, e) -> {
            System.err.println("Message processing rejected, queue is full");
        });
        executor.initialize();
        return executor;
    }

    /**
     * 异步处理UDP消息
     */
    @Async("messageExecutor")
    public void processMessageAsync(byte[] receivedBytes ,InetSocketAddress sender, ChannelHandlerContext ctx) {
        try {
            // 1. 业务逻辑处理
            handleBusinessLogic(receivedBytes);

            // 2. 发送响应（如果需要）
            sendResponse(ctx, sender, receivedBytes);
        } catch (Exception e) {
            // 业务异常处理
            e.printStackTrace();
        }
    }

    // 实际业务处理逻辑
    private void handleBusinessLogic(byte[] receivedBytes) {
        final String receiveHexStr = HexUtil.encodeHexStr(receivedBytes);
        System.out.println("接收到消息:" + receiveHexStr);
    }

    private void sendResponse(ChannelHandlerContext ctx, InetSocketAddress sender, byte[] receivedBytes) {
        // 发送响应
        DatagramPacket responsePacket = new DatagramPacket(Unpooled.copiedBuffer(receivedBytes), sender);
        ctx.writeAndFlush(responsePacket);
    }
}
    